const ImmediatePriority = 1; // 立即执行的优先级, 级别最高 [点击事件，输入框，]
const UserBlockingPriority = 2; // 用户阻塞级别的优先级, [滚动，拖拽这些]
const NormalPriority = 3; // 正常的优先级 [redner 列表 动画 网络请求]
const LowPriority = 4; // 低优先级  [分析统计]
const IdlePriority = 5;// 最低阶的优先级, 可以被闲置的那种 [console.log]

function getCurrentTime() {
    return performance.now(); // 精准 精确到微秒
}

class SimpleScheduler {
    constructor() {
        /**
         * {
         *  callback
         *  priorityLevel
         *  expirationTime
         * }
         */
        this.taskQueue = [];
        this.isPerformingWork = false; // 是否正在工作 防止重复调度
        const channel = new MessageChannel();
        this.port = channel.port2 // 发消息的
        channel.port1.onmessage = this.performWorkUntilDeadline.bind(this);
        // this.timerQueue = [];
        // this.taskIdCounter = 1;
        // this.currentTask = null;
        // this.currentPriorityLevel = NormalPriority;
    }

    /**
     * 
     * @param {优先级} priorityLevel 
     * @param {回调函数} callback 
     */
    scheduleCallback(priorityLevel, callback) {
        const currentTime = getCurrentTime();
        let timeout;
        // 根据优先级设置超时时间
        // 超时时间越小，优先级越高
        switch (priorityLevel) {
            case ImmediatePriority:
                timeout = -1;
                break;
            case UserBlockingPriority:
                timeout = 250;
                break;
            case LowPriority:
                timeout = 10000;
                break;
            case IdlePriority:
                timeout = 1073741823; // 32位操作系统V8引擎所对应的最大时间
                break;
            case NormalPriority:
            default:
                timeout = 5000;
                break;
        }

        const task = {
            callback,
            priorityLevel,
            expirationTime: currentTime + timeout // 直接根据当前时间加上超时时间
        }
        this.push(this.taskQueue, task); // 将任务加入队列
        this.schedulePerformWorkUntilDeadline();
    }

    schedulePerformWorkUntilDeadline(){
        if (!this.isPerformingWork){
            this.isPerformingWork = true
            this.port.postMessage(null) //触发调度
        }
        
    }

    performWorkUntilDeadline(){
        // console.log(this, 'performWorkUntilDeadline');
        this.isPerformingWork = true
        this.workLoop();
        this.isPerformingWork = false
    }

    workLoop(){ 
        // 执行任务
        let currentTask = this.peek(this.taskQueue);
        while(currentTask){
            let cb = currentTask.callback;
            cb && cb();
            this.pop(this.taskQueue)
            currentTask = this.peek(this.taskQueue);
        }
    }

    push(queue, task){ 
        queue.push(task);
        queue.sort((a, b) => a.expirationTime - b.expirationTime); // 从小到大排序
    }

    peek(queue){
        return queue[0] || null;
    }

    pop(queue){
        return queue.shift();
    }



}

const s = new SimpleScheduler();

// 可以被调用多次 代码是顺序可以乱写，但是执行的顺序是不能乱，优先级高的先执行
// sort 
s.scheduleCallback(UserBlockingPriority, () => { console.log('UserBlockingPriority') });
s.scheduleCallback(ImmediatePriority, () => { console.log('ImmediatePriority') });
